package com.ruoyi.work.service.impl;

import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.work.domain.WorkFill;
import com.ruoyi.work.domain.enums.CheckType;
import com.ruoyi.work.domain.vo.WorkFillVo;
import com.ruoyi.work.domain.vo.WorkFillDetailVo;
import com.ruoyi.work.domain.vo.WorkFillProjectReport;
import com.ruoyi.work.domain.vo.WorkFillReport;
import com.ruoyi.work.mapper.WorkDeclarerMapper;
import com.ruoyi.work.mapper.WorkFillMapper;
import com.ruoyi.work.service.IWorkFillService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author: MMDZ
 * @Desc:
 */
@Service
public class WorkFillServiceImpl implements IWorkFillService {

    @Autowired
    private WorkFillMapper workFillMapper;

    /**
     * 初始化填报数据（今天已填写的填报记录）
     *
     * @return
     */
    @Override
    public AjaxResult init() {
        Long userId = SecurityUtils.getUserId();
        List<WorkFill> init = workFillMapper.initWorkFill(userId);
        return AjaxResult.success(init);
    }

    /**
     * 工时填报（同一日期 填报时间不超过24小时）
     *
     * @param vo
     * @return
     */
    @Override
    @Transactional
    public AjaxResult insertWorkFill(WorkFillVo vo) {
        // 个人提交的报工明细
        List<WorkFillDetailVo> details = vo.getFillDetails();
        // 统计 每个日期 工时总和（提取时间-格式 yyyy-dd-mm）
        Map<String, Double> detailMap = details.stream().collect(
                Collectors.groupingBy(e -> DateUtils.dateTime(e.getWorkTime()),
                        Collectors.summingDouble(WorkFillDetailVo::getWorkHour)));
        // 提取日期（'2022-04-07','2022-04-06'）
        String fillTimeStr = details.stream().map(e -> DateUtils.dateTime(e.getWorkTime())).distinct().collect(Collectors.joining(","));
        // 根据用户和填报日期查询 对应日期的工时总和
        List<WorkFillDetailVo> resList = workFillMapper.selectSumTimeByFillAndUserId(vo.getUserId(), fillTimeStr);

        // 校验同一日期 填报时间不超过24小时
        resList.forEach(e -> {
            Double sumHour = detailMap.get(DateUtils.dateTime(e.getWorkTime()));
            if (sumHour + e.getWorkHour() > 24)
                throw new ServiceException("申报日期：" + DateUtils.dateTime(e.getWorkTime()) + " 填报工时总和已超过 24 小时，请修改", HttpStatus.ERROR);
        });

        // 新增
        for (WorkFillDetailVo fillDetail : details) {
            WorkFill workFill = new WorkFill();
            workFill.setUserId(vo.getUserId());
            workFill.setFillStartTime(vo.getFillStartTime());
            workFill.setFillEndTime(vo.getFillEndTime());
            workFill.setProjectId(fillDetail.getProjectId());
            workFill.setStageId(fillDetail.getStageId());
            workFill.setOfficeId(fillDetail.getOfficeId());
            workFill.setWorkTime(fillDetail.getWorkTime());
            workFill.setWorkHour(fillDetail.getWorkHour());
            workFill.setWorkRemark(fillDetail.getWorkRemark());

            workFill.setFillState(CheckType.Waiting.getCode()); // 初始状态-待审核
            workFill.setCreateBy(SecurityUtils.getUsername());
            workFillMapper.insertWorkFill(workFill);
        }
        return AjaxResult.success();
    }

    /**
     * 我的工时-工时累计（审核过的有效工时）
     *
     * @param report
     * @return
     */
    @Override
    public List<WorkFillReport> initFill(WorkFillReport report) {
        Long userId = SecurityUtils.getUserId();
        report.getParams().put("userId", userId);
        return workFillMapper.initWorkFillReport(report);
    }

    /**
     * 我的工时-累计项目工时（审核过的有效工时）
     *
     * @param report
     * @return
     */
    @Override
    public List<WorkFillProjectReport> initPro(WorkFillProjectReport report) {
        Long userId = SecurityUtils.getUserId();
        report.getParams().put("userId", userId);
        return workFillMapper.initWorkFillProjectReport(report);
    }

    /**
     * 查询个人申报回退列表
     *
     * @param workFill
     * @return
     */
    @Override
    public List<WorkFill> selectFillForRollBackList(WorkFill workFill) {
        Long userId = SecurityUtils.getUserId();
        workFill.setUserId(userId);
        return workFillMapper.selectFillForRollBackList(workFill);
    }

    /**
     * 根据id查询填报详情信息
     *
     * @param fillId
     * @return
     */
    @Override
    public WorkFill selectWorkFillById(Long fillId) {
        return workFillMapper.selectWorkFillById(fillId);
    }

    /**
     * 申报回退-审核回退后-删除填报信息
     *
     * @param fillId
     * @return
     */
    @Override
    public int deleteWorkFillById(Long fillId) {
        return workFillMapper.deleteWorkFillById(fillId);
    }

    /**
     * 申报回退-审核回退后-修改后的信息
     *
     * @param workFill
     * @return
     */
    @Override
    public int updateBackWorkFill(WorkFill workFill) {
        if (Objects.isNull(workFill.getFillId()))
            throw new ServiceException("获取申报编号信息异常，请联系管理员", HttpStatus.ERROR);
        WorkFill fill = selectWorkFillById(workFill.getFillId());
        if (Objects.isNull(fill))
            throw new ServiceException("获取申报信息异常，请联系管理员", HttpStatus.ERROR);

        // 校验同一日期 填报时间不超过24小时
        List<WorkFill> resList = workFillMapper.checkFillVerifyTime(workFill);
        Double sumWorkHour = resList.stream().collect(Collectors.summingDouble(WorkFill::getWorkHour));
        if (sumWorkHour + workFill.getWorkHour() > 24)
            throw new ServiceException("申报日期：" + DateUtils.dateTime(workFill.getWorkTime()) + " 填报工时总和已超过 24 小时，请修改", HttpStatus.ERROR);

        workFill.setFillState(CheckType.Waiting.getCode());
        return workFillMapper.updateBackWorkFill(workFill);
    }
}
